<?php

namespace App\Command\ResumeParsing\Service;

use App\Command\ResumeParsing\Service as Service;

use \DOMDocumemt;
use \DOMDocumemt\DOMNode;
use EchoPHP\Facades\Log;
use PhpOffice\PhpSpreadsheet;

//读简历文件类
class ReadFileHelper {
    private $name;
    private $functionObj = null;
    public $dict = array();

    function __construct() {
        $this->functionObj = new Service\ParsingFunction();
        //$this->name = "MyDestructableClass";
    }

    function __destruct() {
        //print "Destroying " . $this->name . "\n";
    }

    //根据指定渠道类型选择读取方式(已改为根据文件类型选择读取方式)
    function read(&$taskInfo, $autoTry = false) {
        //获取文件类型
        $filePathArr = explode('.', $taskInfo['filepath']);
        $fileType = strtolower(end($filePathArr));
        switch ($fileType) {
            case 'txt':
                $primaryFuncName = 'readTxt';
                break;
            case 'pdf':
                $primaryFuncName = 'readPdfToText';
                break;
            case 'docx':
                $primaryFuncName = 'readWordDocxToText';
                break;
            case 'doc':
                $primaryFuncName = 'readOriginalWordDocToText';
                break;
            case 'mht':
            case 'html':
                $primaryFuncName = 'readMhtToText';
                break;
            case 'xls':
            case 'xlsx':
                $primaryFuncName = 'readExcel';
                break;
            default:
                $primaryFuncName = 'readHtmlWordDocToText';
                break;
        }
        if (empty($primaryFuncName)) return false;

        $resumeTxtArr = $this->$primaryFuncName($taskInfo['filepath']);

        if (!empty($resumeTxtArr) && is_array($resumeTxtArr)) {
            return $resumeTxtArr;
        }
        if (!file_exists(rtrim(FILESERVER, '/') . "/" . ltrim($taskInfo['filepath'], '/'))) {
            return false;
        }
        if ($autoTry) {
            foreach (['readWordDocxToText', 'readOriginalWordDocToText', 'readMhtToText', 'readHtmlWordDocToText', 'readExcel', 'readPdfToText'] as $funcName) {
                if ($funcName == $primaryFuncName) continue;
                $resumeTxtArr = $this->$funcName($taskInfo['filepath']);
                if (!empty($resumeTxtArr) && is_array($resumeTxtArr)) return $resumeTxtArr;
            }
        }

        return false;
    }

    function readTxt($filePath) {
        $filePath = rtrim(FILESERVER, '/') . "/" . ltrim($filePath, '/');
        if (empty($filePath) || strlen($filePath) < 4) {
            return false;
        }
        try {
            $file = fopen($filePath, "r");
            $resumeText = fread($file, filesize($filePath));
            fclose($file);
            if (empty($resumeText)) {
                Log::error('txt文件内容读取失败', ['filePath' => $filePath], 'cmd');
                return false;
            }
            $resumeTxtArr = array('resumeBase' => $resumeText, 'resumeAtom' => $resumeText, 'resumeSection' => $resumeText, 'resumeDom' => null);
            return $resumeTxtArr;
        } catch (\Exception $e) {
            Log::error(e_dump($e), ['filePath' => $filePath], 'cmd');
            return false;
        }
    }

    function readExcel($filePath) {
        $filePath = rtrim(FILESERVER, '/') . "/" . ltrim($filePath, '/');
        if (empty($filePath) || strlen($filePath) < 4) {
            return false;
        }
        try {
            $sourceWorkbook = PhpSpreadsheet\IOFactory::load($filePath);
            if ($sourceWorkbook->getSheetCount() < 1) {
                Log::error('excel文件读取为空', ['filePath' => $filePath], 'cmd');
                return false;
            }

            $resumeSheet = $sourceWorkbook->getSheet(0);

            if ($sourceWorkbook->getSheetCount() == 1 && $resumeSheet->getTitle() == 'Worksheet') {
                Log::error('非法excel文件', ['filePath' => $filePath], 'cmd');
                return false;
            }   //Word文档可能被误判为Excel
            if ($resumeSheet->getHighestRow() == 1 && $resumeSheet->getHighestColumn() == 'A') {
                Log::error('excel读取无效数据', ['filePath' => $filePath], 'cmd');
                return false;
            }


            //删除excel简历中的英文部分
//            if ($resumeSheet->getHighestColumn() > 'D') {
//                $resumeSheet->removeColumn('D');//一般英文英文部分在D列后三列，进行删除
//            }
            //var_dump($arr);
            return ['resumeBase' => '', 'resumeAtom' => '', 'resumeSection' => '', 'resumeDom' => null, 'resumeSheet' => $resumeSheet];
        } catch (\Exception $e) {
            Log::error(e_dump($e), ['filePath' => $filePath], 'cmd');
            return false;
        }
    }

    //  功能已被multipartreader覆盖

    /**
     * 读取Base64格式文件
     * @param $filePath
     * @return resumeText
     * @return array|bool
     */
    /*
    function readBaseToText($filePath) {
        if (empty($filePath) || strlen($filePath) < 4) {
            return false;
        }

        $resumeText = file_get_contents($filePath);

        $isValidBase64 = FALSE;

        //需要根据内容定位动态截取
        $charset = 'utf-8';
        if (preg_match('/Content-Type:multipart(?:[^;]*;)+boundary=(?<quote>")?(?<boundary>[^\s;"]+)(?(quote)")/i', $resumeText, $multipartResult)) {
            if ($multipartResult['boundary']) {
                if (preg_match('/' . preg_quote($multipartResult['boundary'], '/') . '(?:\r\n|[\r\n])+(?:(?:Content-Transfer-Encoding[^\S\r\n]*:[^\S\r\n]*base64\b[^\r\n]*|Content-Type[^\S\r\n]*:[^\S\r\n]*(?<ContentType>[^\s;]*html[^\s;]*)(?:[^;]*;[^\S\r\n]*)*charset[^\S\r\n]*=[^\S\r\n]*(?<quote>")?(?<charset>(?<=")(?:[^"]+)(?=")|[^\s"]+)(?(quote)")[^\S\r\n]*)(?:\r\n|[\r\n])+){2,}^(?<base64>(?:[A-Za-z0-9+\/]{4}\r?\n?)+(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?)$/mi', $resumeText, $parseResult)) {
                    $charset = $parseResult['charset'];
                    $resumeText = $parseResult['base64'];
                    $isValidBase64 = TRUE;
                }
            }
        }
        //var_dump($resumeText);
        if (!$isValidBase64) {
            if (!preg_match('/^(?:[A-Za-z0-9+\/]{4}\r?\n?)+(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?$/', $resumeText)) {
                return false;
                //return array('resumeBase' => '', 'resumeAtom' => '', 'resumeSection' => '', 'resumeDom' => null);
            }
        }

        //需要根据编码格式动态解析
        if ($resumeText === FALSE) return false;;//return array('resumeBase' => '', 'resumeAtom' => '', 'resumeSection' => '', 'resumeDom' => null);
        $resumeText = base64_decode($resumeText);
        if ($resumeText === FALSE) return false;;//return array('resumeBase' => '', 'resumeAtom' => '', 'resumeSection' => '', 'resumeDom' => null);
        //var_dump($resumeText);
        //$resumeText = @iconv('gbk',"utf-8//IGNORE",$resumeText);
        $resumeText = str_replace('charset=gb2312', 'charset=gbk', $resumeText);

        //创建DOMDocument对象
        $domObject = new \DOMDocument();
        //$resumeText = str_replace(iconv('utf-8',"gbk//IGNORE",'斐飏'), iconv('utf-8',"gbk//IGNORE",'测试'), $resumeText);
        //var_dump($resumeText); exit;

        #$domObject->formatOutput = true; //不知道是不是我的理解问题，这个选项格式化出来的并不完美
        @$domObject->loadHTML($resumeText);

        $resumeAtom = $this->domDocToText($domObject->documentElement, 0, $domObject, true);
        $resumeSection = $this->domDocToText($domObject->documentElement, 0, $domObject, false);
        $resumeTxtArr = array('resumeBase' => $resumeText, 'resumeAtom' => $resumeAtom, 'resumeSection' => $resumeSection, 'resumeDom' => $domObject);
        return $resumeTxtArr;
    }*/

    /**
     * 读取Mht格式文件
     * @param string $filePath 完整路径
     * @return array|bool 简历数据结构，失败返回false
     */
    function readMhtToText(string $filePath) {
        $filePath = rtrim(FILESERVER, '/') . "/" . ltrim($filePath, '/');
        if (empty($filePath) || strlen($filePath) < 4) {
            return false;
        }
        try {
            $resumeText = '';
            $mreader = new MultipartReader();
            $mreader->autoProcess = 'html,image';
            $mreader->read($filePath);

            if (!$mreader->isValid) {
                Log::error('非法multipart文件', ['filePath' => $filePath], 'cmd');
                return false;
            }

            $htmlParts = [];
            $imgParts = [];
            foreach ($mreader as $part) {
                if ($mreader->contentIs($part, 'html')) {
                    $htmlParts[] = &$part['Content'] ?? '';
                } elseif ($mreader->contentIs($part, 'image')) {
                    if (empty($part['Content'])) continue;
                    $img = ['data' => &$part['Content']];
                    if (!empty($part['content-type']['value'])) $img['mime'] =& $part['content-type']['value'];
                    if (!empty($part['content-location']['value'])) $imgParts[$part['content-location']['value']] = $img;
                    if (!empty($part['content-id']['value'])) {
                        $cid = $part['content-id']['value'];
                        if (preg_match('/^<(.+)>$/', $cid, $matches)) $cid = $matches[1];
                        $imgParts['cid:' . $cid] = $img;
                    }
                }
            }
            if (empty($htmlParts)) {
                Log::error('multipart文件格式不合法', ['filePath' => $filePath], 'cmd');
                return false;
            }
            $resumeBase = $resumeText = $htmlParts[0];
            if (empty($resumeText)) {
                Log::error('multipart文件读取内容为空', ['filePath' => $filePath], 'cmd');
                return false;
            }
            //创建DOMDocument对象
            $domObject = new \DOMDocument();
            #$domObject->formatOutput = true; //不知道是不是我的理解问题，这个选项格式化出来的并不完美
            if (!@$domObject->loadHTML($resumeText)) {
                Log::error('multipart文件格式不合法', ['filePath' => $filePath], 'cmd');
                return false;
            }

            $resumeAtom = $this->domDocToText($domObject->documentElement, 0, $domObject, true);
            $resumeSection = $this->domDocToText($domObject->documentElement, 0, $domObject, false);
            //var_dump('debug1');
            //var_dump($resumeAtom); exit;
            $resumeTxtArr = array('resumeBase' => $resumeBase, 'resumeAtom' => $resumeAtom, 'resumeSection' => $resumeSection, 'resumeImage' => $imgParts, 'resumeDom' => $domObject);
            return $resumeTxtArr;
        } catch (\Exception $e) {
            Log::error(e_dump($e), ['filePath' => $filePath], 'cmd');
            return false;
        }
    }
    /*
        //针对Mht格式的文件进行解析  这个方法有问题，暂不使用
        function readMhtToText2($filePath) {
            if (empty($filePath) || strlen($filePath) < 4) {
                return false;
            }
            if (!file_exists($filePath)) {
                 return false;
            }
            if (is_dir($filePath)){
                 return false;
            }

            if (strpos(strtolower($filePath), '.mht', 1) == FALSE){
                 return false;
            }

            include('./Service/ResumeParsing/MhtToHtmlHelper.php');
            $mhtToHtml = new \Service\ResumeParsing\MhtToHtml();
            $mhtToHtml->set_file($filePath);
            $mhtToHtml->extract();
            $resumeText = $mhtToHtml->get_all_part_file();

            //$resumeText = $mhtToHtml->get_part_to_file(0);

            $resumeTxtArr = array('resumeBase' =>$resumeText, 'resumeAtom' =>$resumeText, 'resumeSection' =>$resumeText, 'resumeDom' => $domObject);
            return $resumeTxtArr;
        }
    */
    /**
     * 读取doc格式文件
     * @return resumeText
     */
    function readHtmlWordDocToText($filePath) {
        $filePathTmp = rtrim(FILESERVER, '/') . "/" . ltrim($filePath, '/');
        if (empty($filePathTmp) || strlen($filePathTmp) < 4) {
            return false;
        }
        try {
            $resumeText = @file_get_contents($filePathTmp);
            $resumeBase = $resumeText;

            //创建DOMDocument对象
            $domObject = new \DOMDocument();
            $domObject2 = new \DOMDocument();
            #$domObject->formatOutput = true; //不知道是不是我的理解问题，这个选项格式化出来的并不完美
            $status = @$domObject->loadHTMLFile($filePathTmp);
            $xPath = new \DOMXPath($domObject);
            if (!count($xPath->query('//*[5]'))) {
                $status = false;    //通过标签数量过少判断出不是正常html
            } else {
                $mreader = new MultipartReader(); //multipart文件可能被误认为原始html，需排除这种情况
                if ($mreader->test($filePathTmp)) {
                    $status = false;
                }
            }

            if ($status) {
                @$domObject2->loadHTMLFile($filePathTmp);  //创建副本，该副本不被修改，直接用作dom解析逻辑
                $resumeAtom = $this->domDocToText($domObject->documentElement, 0, $domObject, true);
                $resumeSection = $this->domDocToText($domObject->documentElement, 0, $domObject, false);
                $resumeTxtArr = array('filePath' => $filePathTmp, 'resumeBase' => $resumeBase, 'resumeAtom' => $resumeAtom, 'resumeSection' => $resumeSection, 'resumeDom' => $domObject2);
                return $resumeTxtArr;
            }
            Log::error('不是合法doc文件', ['filePath' => $filePath], 'cmd');
            $resumeTxtArr = $this->readMhtToText($filePath);
            if (!empty($resumeTxtArr) && is_array($resumeTxtArr)) {
                return $resumeTxtArr;
            }
            Log::error('不是合法multipart文件', ['filePath' => $filePath], 'cmd');
            //尝试DOM方式解析，如果解析失败，则应该是标准的微软doc简历。
            //if (empty($domObject->textContent) && FALSE) {
//            if (substr($filePath,-4,4) == '.doc') {
//                $resumeText = $this->readOriginalWordDocToText($filePath);
//                if (!empty($resumeText)) {
//                    return $resumeText;
//                }
//            }
            return false;
            //$domObject->saveHTML();
            //$xPath = new DOMXPath($dom);
            //$stu_nodes =$dom->getElementsByTagName("body");
            //get all elements with a particular id and then loop through and print the href attribute
            //$elements = $xPath->query('//*[@id="lg"]/img/@src'); //$elements = $xPath->query('//body');
            //foreach ($elements as $e) {}
        } catch (\Exception $e) {
            Log::error(e_dump($e), ['filePath' => $filePathTmp], 'cmd');
            return false;
        }
    }

    /**
     * 读取doc格式文件
     * @return resumeText
     */
    function readOriginalWordDocToText(&$filePath) {
        $filePathTmp = rtrim(FILESERVER, '/') . "/" . ltrim($filePath, '/');
        if (empty($filePathTmp) || strlen($filePathTmp) < 4) {
            return false;
        }
        try {
            //doc文件首先采用antiword读取
            $resumeText = shell_exec(config('app.resume_machine_learning.antiword_cmd') . $filePathTmp);
            //换行符替换成char(16)
            $resumeText = str_replace("\r", '', $resumeText);
            $resumeText = str_replace("\n", chr(16), $resumeText);
            $resumeText = preg_replace('/\s*?[：:\|]\s*?/u',chr(16),$resumeText);
            //file_put_contents(ROOT_PATH.'/app/Command/ResumeParsing/out.txt',$resumeText);
            if (empty($resumeText)) {
                Log::error('antiword读取文件失败，转用dom解析', ['filePath' => $filePath], 'cmd');
                //antiword读取不了的使用dom解析
                $resumeTxtArr = $this->readHtmlWordDocToText($filePath);
                if (!empty($resumeTxtArr) && is_array($resumeTxtArr)) {
                    return $resumeTxtArr;
                }
                Log::error('dom解析失败，尝试转为docx进行解析', ['filePath' => $filePath], 'cmd');
                //再不行的用libreoffice转换成docx格式再读取
                $filePathArr = explode('/', $filePathTmp);
                array_pop($filePathArr);
                $fileDir = implode('/', $filePathArr);
                $cmd = config('app.resume_machine_learning.libreoffice_cmd') . $filePathTmp . ' --outdir ' . $fileDir;
                $result = shell_exec($cmd);
                if (!empty($result)) {
                    $filePath = $filePath . 'x';
                    $resumeTxtArr = $this->readWordDocxToText($filePath);
                    if (!empty($resumeTxtArr) && is_array($resumeTxtArr)) {
                        $resumeTxtArr['tmpFile'] = true;
                        return $resumeTxtArr;
                    }
                }
                Log::error('lireoffice解析失败', ['filePath' => $filePath], 'cmd');
                return false;
            }
//            $resumeText = $this->charsetToGBK($resumeText);
//            $resumeText = $this->charsetToUTF8($resumeText);
            $resumeTxtArr = array('resumeBase' => $resumeText, 'resumeAtom' => $resumeText, 'resumeSection' => $resumeText, 'resumeDom' => null);
            return $resumeTxtArr;
        } catch (\Exception $e) {
            Log::error(e_dump($e), ['filePath' => $filePath], 'cmd');
            return false;
        }
    }
    /**
     * 将非GBK字符集的编码转为GBK
     *
     * @param mixed $mixed 源数据
     *
     * @return mixed GBK格式数据
     */
    function charsetToGBK($mixed) {
        $encode = mb_detect_encoding($mixed, array('ASCII', 'UTF-8', 'GB2312', 'GBK', 'BIG5'));
        if ($encode == 'UTF-8') {
            $mixed = iconv('UTF-8', 'GBK//IGNORE', $mixed);
        }
        return $mixed;
    }
    /**
     * 将非UTF-8字符集的编码转为UTF-8
     *
     * @param mixed $mixed 源数据
     *
     * @return mixed utf-8格式数据
     */
    function charsetToUTF8($mixed) {
//        $encode = mb_detect_encoding($mixed, array('ASCII', 'UTF-8', 'GB2312', 'GBK', 'BIG5'));
        $mixed = iconv('GBK', 'UTF-8//IGNORE', $mixed);

        return $mixed;
    }

    /**
     * 读取pdf格式文件转成txt并输出
     * @param $filePath
     * @return array|bool
     */
    function readPdfToText($filePath) {
        $filePath = rtrim(FILESERVER, '/') . "/" . ltrim($filePath, '/');
        if (empty($filePath) || strlen($filePath) < 4) {
            return false;
        }
        try {
            $resumeText = shell_exec(config('app.resume_machine_learning.pdftotext_cmd') . $filePath . " -");
            $resumeText = str_replace("\n", chr(16), $resumeText);
            $resumeText = str_replace("\r", '', $resumeText);
            if (empty($resumeText)) {
                Log::error('xpdf读取文件失败', ['filePath' => $filePath], 'cmd');
                return false;
            }
//            $resumeText = $this->charsetToGBK($resumeText);
//            $resumeText = $this->charsetToUTF8($resumeText);
            $resumeTxtArr = array('resumeBase' => $resumeText, 'resumeAtom' => $resumeText, 'resumeSection' => $resumeText, 'resumeDom' => null);
            return $resumeTxtArr;
        } catch (\Exception $e) {
            Log::error(e_dump($e), ['filePath' => $filePath], 'cmd');
            return false;
        }

    }

    /**
     * 使用ZipArchive读取docx格式文件 //https://blog.csdn.net/robin_sky/article/details/82737136  //https://www.jianshu.com/p/7d032dc34219
     * @return resumeText
     */
    function readWordDocxToText($filePath) {
        $filePath = rtrim(FILESERVER, '/') . "/" . ltrim($filePath, '/');
        if (empty($filePath) || strlen($filePath) < 4) {
            return false;
        }
        try {
            /* 用zip压缩读取word中内容 */
            $zip = new \ZipArchive;
            $zipFlag = $zip->open($filePath);
            if ($zipFlag != true) {
                Log::error('docx文件解压失败', ['filePath' => $filePath], 'cmd');
                return false;
            }

            $resumeText = '';
            $resumeBase = '';
            $resumeAtom = '';
            $resumeSection = '';
            $documentXmlRels = '';
            //创建DOMDocument对象
            $domObject = new \DOMDocument();
            $domObject2 = new \DOMDocument();

            for ($i = 0; $i < $zip->numFiles; $i++) {
                $zipFile = $zip->statIndex($i);
                //word内容，父级xml
                if ($resumeText == '' && $zipFile['name'] == "word/document.xml") {
                    $resumeText = $zip->getFromIndex($i);

                    mb_internal_encoding("UTF-8");
                    mb_regex_encoding('utf-8');
                    $resumeBase = $resumeText;
                    //$resumeText = mb_ereg_replace("[\r\t\n　]", "", $resumeText);
                    //$resumeText = preg_replace("/<!--(?!\[if ).*?-->/us", " ", $resumeText);

                    if (!@$domObject->loadHTML($resumeText)) return false;
                    if (!@$domObject2->loadHTML($resumeText)) return false;

                    $resumeAtom = $this->domDocToText($domObject->documentElement, 0, $domObject, true);
                    $resumeSection = $this->domDocToText($domObject->documentElement, 0, $domObject, false);

                    //$xPath = new DOMXPath($domObject);
                    //工作年限：
                    //get all elements with a particular id and then loop through and print the href attribute
                    //<w:t xml:space="preserve">工作年限：8 年以上 </w:t>
                    //$domObject->loadXML("<name>'bla' \"bla\" bla</name>");

                    /*
                    $domObject->loadHTML("<html><body>
                    <div>'bla' \"bla\" bla</div>
                    <div>'bla' \"bla\" bla</div>
                    <w:t xml:space=\"preserve\">工作年限：8 年以上 </w:t>
                    </body></html>");
                    $xpath = new DOMXPath($domObject);
                    $elements = $xpath->query("//div[text()=concat(\"'bla' \" ,'\"bla\"' ,\" bla\")]");

                    //$elements = $xPath->query('//w:t xml:space="preserve">');
                    var_dump($elements);
                    //$elements = $xpath->query("*div[@id='yourTagIdHere']");
                    //$elements = $xPath->query('//body');
                    if (!is_null($elements)) {
                        foreach ($elements as $element) {
                            echo "<br/>[". $element->nodeName. "]";

                            $nodes = $element->childNodes;
                            foreach ($nodes as $node) {
                                echo $node->nodeValue. "\n";
                            }
                        }
                    }
                    exit();
                    */
                }
                //子级xml
                if ($zipFile['name'] == "word/_rels/document.xml.rels") {
                    $documentXmlRels = $zip->getFromIndex($i);
                }
            }

            $imgParts = [];
            /* 读取图片 */
            for ($i = 0; $i < $zip->numFiles; $i++) {
                if (empty($zipFile = $zip->statIndex($i)) || preg_match('/\.(?:xml|rels)$/ui', $zipFile['name'])) continue;
                $zipFile['data'] = $zip->getFromIndex($i);
                $imgParts[preg_replace('/^word\//i', '', $zipFile['name'])] = $zipFile;
            }
            if (!empty($documentXmlRels)) {
                $xml = new \DOMDocument();
                $xml->loadXML($documentXmlRels, LIBXML_NOENT | LIBXML_XINCLUDE | LIBXML_NOERROR | LIBXML_NOWARNING);
                $xPath = new \DOMXPath($xml);
                $imgDict = [];
                foreach ($imgParts as $name => &$img) {
                    $nodes = $xPath->query("/*/*[@Target='" . $name . "'][1]/@Id");
                    if (!count($nodes)) continue;
                    $imgDict[$nodes[0]->textContent] =& $img;
                    unset($imgParts[$name]);
                }
                $imgParts += $imgDict;
            }
            /*if (preg_match("([^\s]+(\.(?i)(jpg|jpeg|png|gif|bmp))$)", $zipFile['name'])) {
                $existImages = array();
                $imageUrl = './img/';
                $rand = uniqid();
                $file = "{$rand}.png";
                $imageFile = $imageUrl . "{$file}";
                $im = imagecreatefromstring($zip->getFromIndex($i));
                //生成处理过图片，给模糊接口使用
                $imWidth = imagesx($im);
                $imHeight = imagesy($im);
                if ($imWidth > 580) {
                    $fixWidth = 580;  //生成图片的固定宽度
                    $newHeight = intval($fixWidth / $imWidth * $imHeight);
                    $newIm = imagecreatetruecolor($fixWidth, $newHeight);
                    imagecopyresampled($newIm, $im, 0, 0, 0, 0, $fixWidth, $newHeight, $imWidth, $imHeight);  //调整图片大小
                    imagepng($newIm, $imageFile);  //生成图片
                    imagedestroy($im);
                    imagedestroy($newIm);
                } else {
                    imagepng($im, $imageFile);  //生成图片
                    imagedestroy($im);
                }
                $a = getFileName($zipFile['name']);

                $existImages[$zipFile['name']] =  $imageUrl . $file;
                var_dump($existImages);
            }
            */

            if (empty($resumeAtom)) {
                Log::error('docx方式读取文件失败', ['filePath' => $filePath], 'cmd');
                return false;
            }
            $resumeTxtArr = array('resumeBase' => $resumeBase, 'resumeAtom' => $resumeAtom, 'resumeSection' => $resumeSection, 'resumeDom' => $domObject2, 'resumeImage' => $imgParts);
            return $resumeTxtArr;
        } catch (\Exception $e) {
            Log::error(e_dump($e), ['filePath' => $filePath], 'cmd');
            return false;
        } finally {
            if (!empty($zip)) @$zip->close();
        }
    }

    //解析DOMDocument内容为文本
    function domDocToText(\DOMNode $node, $treeIndex = 0, $domObject, $isTerminal) {
        //https://www.php.net/manual/en/class.domdocument.php
        //不格式化的标签
        $strResult = '';
        if (in_array($node->nodeName, ['head', 'title', 'style'])) {
            return $strResult;
        }

        $tagArr = array("p", "b", "span", "spanlang");  //"div", "tr", "td",
        if (@$node->tagName != "" && @$node->nodeValue != "") {
            //var_dump(@$node->tagName);
        }
        if (!$isTerminal && in_array(strtolower(@$node->tagName), $tagArr)) {
            $strResult = chr(16) . chr(16);

            //需要提取识别图片时，不能用此方法
            /*
            $tmpValue = $this->functionObj->formatTxt($node->nodeValue,true);
            if($tmpValue != ''){
                $strResult .= htmlspecialchars($tmpValue);
            }
            return $strResult;
            */
        }

        /*
        //<w:t xml:space="preserve">工作年限：8 年以上 </w:t>
        if(@$node->nodeName=="t"){
            //<a:blip r:embed="rId7" />
            if(startWith($node->nodeValue,'工作年限：')){
                var_dump($node->nodeValue);
            }
            if(startWith($node->nodeValue,'目前职业概况')){
                var_dump($node->nodeValue);
            }
        }

        if(@$node->nodeName=="blip"){
            //<a:blip r:embed="rId7" />
            var_dump($node->getAttribute("r:embed"));
        }
        */

        if ($node->hasChildNodes()) {
            $treeIndex++;
            $tabStart = "\r\n" . str_repeat("\t", $treeIndex);
            $tabEnd = "\r\n" . str_repeat("\t", $treeIndex - 1);
            $i = 0;
            while ($childNode = $node->childNodes->item($i++)) {
                if ($childNode->nodeType == XML_TEXT_NODE) {
                    if (ctype_space(str_replace("\xc2\xa0", '', $childNode->nodeValue))) {
                        $node->removeChild($childNode);
                        $i--;
                        continue;
                    }
                    $childNode->nodeValue = trim($childNode->nodeValue);
                }
                $node->insertBefore($node->ownerDocument->createTextNode($tabStart), $childNode);
                $i++;
                $strResult .= $this->domDocToText($childNode, $treeIndex, $domObject, $isTerminal);
            };
            $node->appendChild($node->ownerDocument->createTextNode($tabEnd));
        } else {
            if ($node instanceof \DOMComment) return '';

            if (@$node->nodeName == "blip") {
                //<a:blip r:embed="rId7" />
                $strResult = chr(16) . '联系图片:' . @$node->getAttribute("r:embed");
                //var_dump($node->getAttribute("r:embed"));
                return $strResult;
            }

            $tmpValue = $this->functionObj->formatTxt($node->nodeValue, true);
            if ($tmpValue != '') {
                $strResult = chr(16) . htmlspecialchars($tmpValue);
            }
            //$strResult = '<br/><br/>' . htmlspecialchars($tmpValue);

            //$strResult = '<br/>' . $treeIndex .'______'. htmlspecialchars($tmpValue);

            //$strResult = '<br/>' . $treeIndex .'______'. $tmpValue;
            /*
            if($tmpValue == '内江'){
                var_dump($node->parentNode->parentNode);
                exit();
            }
            */

            //echo ('<br/><br/>');
            //echo ($treeIndex.'=');
            //echo (htmlspecialchars($tmpValue));
            //echo ('____'.$this->functionObj->encode($tmpValue));
        }
        return $strResult;
    }

    /**
     * 使用PHPWorld读取docx格式文件   这个方式处理相当复杂，暂不使用。
     * @return resumeText
     */
    /*
    //$filePath = ROOT_PATH . 'Public/Task/Files/4.需图片识别.docx';
    //$resumeTxtArr = readPHPWordDocxToText($filePath);
    //$resumeTxtArr['resumeText'] = replaceChar16($resumeTxtArr['resumeText']);
    //var_dump($resumeTxtArr['resumeText']);
    //exit();
    */
    /*
    function readPHPWordDocxToText($filePath) {
        if (empty($filePath) || strlen($filePath) < 4) {
            return false;
        }
        try {
            date_default_timezone_set("Asia/Shanghai");
            include ROOT_PATH . 'vendor/autoload.php';
            //读取文件
            //$phpWord = \PhpOffice\PhpWord\IOFactory::load($filePath);

            $objReader = \PhpOffice\PhpWord\IOFactory::createReader('Word2007');
            $phpWord = $objReader->load($filePath);

            $resumeText = '';
            $sections = $phpWord->getSections();
            foreach ($sections as $s) {
                $els = $s->getElements();
                foreach ($els as $e) {
                    if (get_class($e) === 'PhpOffice\PhpWord\Element\TextRun') {
                        $resumeText = getTextElement($e);//获取text节点内容
                    } elseif (get_class($e) === 'PhpOffice\PhpWord\Element\Table') {
                        $rows = count($e1->getRows()); //行数
                        $cells = $e1->countColumns(); //列数
                        //$style=$e->getStyle(); //表格样式
                        //$width=$e->getWidth(); //宽度
                        $arrx['rows'] = $rows;
                        $arrx['cells'] = $cells;

                        for ($i = 0; $i < $rows; $i++) {
                            $rows_a = $e1->getRows()[$i];
                            $arrx['height'][$i + 1] = $rows_a->getHeight();
                            //$arrx['rows'][$i+1]=$this->rowstyle($rows_a);
                            for ($j = 0; $j < $cells; $j++) {
                                //$arrx[$i][$r]=
                                $x = $rows_a->getCells()[$j];
                                $arrx['width'][$i + 1][$j + 1] = $x->getWidth();
                                $arrx['text'][$i + 1][$j + 1] = $this->getTextElement($x);
                                //$arrx['cells'][$i+1][$j+1]=$this->cellsstyle($x);
                            }
                        }
                    } elseif (get_class($e) === 'PhpOffice\PhpWord\Section\TextBreak') {
                        $text .= " \n";
                    } else {
                        throw new Exception('Unknown class type ' . get_class($e));
                    }
                }
            }

            //$objWriter = \PhpOffice\PhpWord\IOFactory::createWriter($objPHPFile, 'HTML');
            //echo $objPHPFile->save('test.html');

            $resumeTxtArr = array('resumeBase' => $resumeText, 'resumeAtom' => $resumeText, 'resumeSection' => $resumeText, 'resumeDom' => $domObject);
            return $resumeTxtArr;
        } catch (\Exception $e) {
            Log::error(e_dump($e), ['filePath' => $filePath], 'cmd');
            return false;
        }
    }
    */

    function docxStyle($e) {
        $style = $e->getFontStyle();
        $arry = $style->getStyleValues();
        foreach ($arry as $key => $xas) {
            if (is_object($xas)) {
                $arry['Paragraph'][] = $xas->getStyleValues();
                unset($arry[$key]);
            }
        }
        return $arry;
    }

    function docxTextArr($e) {
        $textArr['text'] = $e->getText();
        $textArr['style'] = docxStyle($e);
        return $textArr;
    }

    /**
     * 获取Text节点
     */
    function getTextElement($E) {
        $elements = $E->getElements();
        $xas = '';
        $result = [];
        $inResult = [];
        $text = [];
        foreach ($elements as $inE) {
            $ns = get_class($inE);
            $elName = explode('\\', $ns)[3];
            if ($elName == 'Text') {
                $result[] = docxTextArr($inE);
            } elseif (method_exists($inE, 'getElements')) {
                $inResult = $this->getTextElement($inE);
            }
            if (!is_null($inResult)) {
                $result = array_merge($result, $inResult);
            }
        }

        // if (count($result)>0) {
        //     foreach($result as $xaa) {
        //        var_dump($xaa);
        //     }
        // }
        return count($result) > 0 ? $result : null;
    }
}